﻿namespace MySnake {
    //绘制蛇身体 
    export class Draw {

        /**
         * 擦除蛇身
         * @param {Array<SnakeBody>} p_Bodies - 蛇身体集合。
         * @param {HTMLTableElement} p_Table - 游戏容器对象。
         */
        static Erase(p_Bodies: Array<SnakeBody>, p_Table: HTMLTableElement): void {
            for (var i = 0; i < p_Bodies.length; i++) {
                this.EraseDot(p_Bodies[i].X, p_Bodies[i].Y, p_Table);
            }
        }

        /**
         * 擦除点
         * @param {number} x - 单元格的列数。
         * @param {number} y - 单元格的行数。
         * @param {HTMLTableElement} p_Table - 游戏容器对象。
         */
        private static EraseDot(x: number, y: number, p_Table: HTMLTableElement): void {
            (<HTMLTableCellElement>(<HTMLTableRowElement>p_Table.rows[y]).cells[x]).style.backgroundColor = "";
        }


        /**
        * 绘制蛇身
        * @param {Array<SnakeBody>} p_Bodies - 蛇身体集合。
        * @param {HTMLTableElement} p_Table - 游戏容器对象。
        */
        static Paint(p_Bodies: Array<SnakeBody>, p_Table: HTMLTableElement): void {
            for (var i = 0; i < p_Bodies.length; i++) {
                if (i == 0) {
                    this.PaintDot(p_Bodies[i].X, p_Bodies[i].Y, p_Table, this.GetRandomColor());
                } else {
                    this.PaintDot(p_Bodies[i].X, p_Bodies[i].Y, p_Table);
                }
            }
        }

        /**
         * 绘制点
         * @param {number} x - 单元格的列数。
         * @param {number} y - 单元格的行数。
         * @param {HTMLTableElement} p_Table - 游戏容器对象。 
         */
        private static PaintDot(x: number, y: number, p_Table: HTMLTableElement, paintColor: string = "red"): void {
            (<HTMLTableCellElement>(<HTMLTableRowElement>p_Table.rows[y]).cells[x]).style.backgroundColor = paintColor;
        }


        /**
         * 检查下一节点运行状态
         * @param {Array<SnakeBody>} p_Bodies - 蛇身体集合
         * @param {MoveDirection} p_Direction - 运动方向
         * @param {number} p_ColumnCount - 列的数量
         * @param {number} p_RowCount - 行的数量
         * @param {HTMLTableElement} p_Table - 游戏容器对象
         */
        static CheckNextStep(p_Bodies: Array<SnakeBody>, p_Direction: MoveDirection, p_ColumnCount: number, p_RowCount: number, p_Table: HTMLTableElement): number {
            var _NewBody: SnakeBody = this.GetNextPosition(p_Bodies, p_Direction);
            if (_NewBody.X < 0 || _NewBody.X >= p_ColumnCount || _NewBody.Y < 0 || _NewBody.Y >= p_RowCount) {
                return -1; //到达边界, 游戏结束
            }

            /*
            for (var i = 0; i < p_Bodies.length; i++) {
                if (p_Bodies[i].X == _NewBody.X && p_Bodies[i].Y == _NewBody.Y) {
                    return -1; //碰到蛇身，游戏结束
                }
            }
            */

            if (this.IsCellFilled(p_Table, _NewBody.Y, _NewBody.Y)) {
                return 1; //有食物
            }

            //空白行继续运行
            return 0;
        }

        /**
         * 获得蛇头运行下一节点的坐标
         * @param {Array<SnakeBody>} p_Bodies - 蛇身体集合
         * @param {MoveDirection} p_Direction - 运动方向
         */
        static GetNextPosition(p_Bodies: Array<SnakeBody>, p_Direction: MoveDirection): SnakeBody {
            var x = p_Bodies[0].X;
            var y = p_Bodies[0].Y;

            //原点（0，0），上/右/下/左
            switch(p_Direction){
                case MoveDirection.Up:
                    y--;
                break;

                case MoveDirection.Right:
                    x++;
                break;

                case MoveDirection.Down:
                    y++;
                break;

                case MoveDirection.Left:
                    x--;
                break;
            }

            //返回一个坐标
            var _NewBody = new SnakeBody();
            _NewBody.X = x;
            _NewBody.Y = y;
            return _NewBody;
        }

        /**
         * 检查单元格是否被填充
         * @param {HTMLTableElement} p_Table -- 游戏容器的Table
         * @param {number} x - 单元格的列数
         * @param {number} y - 单元格的行数
         */
        static IsCellFilled(p_Table: HTMLTableElement, x: number, y: number): boolean {
            if ((<HTMLTableCellElement>(<HTMLTableRowElement>p_Table.rows[y]).cells[x]).style.backgroundColor == "") {
                return false;
            }
            return true;
        }

        /**
         * 生成随机颜色 -如：'#871ad1'
         */
        static GetRandomColor(): string {
            return '#'+(Math.random()*0xffffff<<0).toString(16);
        }
        
    }
}